using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ProjectCastamere
{
    class Path
    {
        private List<Vector3> points = new List<Vector3>();

        /// <summary>
        /// parallel to the points list; represents the distance from
        /// points[i] to points[i+1]
        /// </summary>
        private List<float> distances = new List<float>();
        float totalDistance = 0.0f;

        /// <summary>
        /// returns the point along the path given the scalar position
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        Vector3 GetPoint(float position)
        {
            if (position < 0.0f)
            {
                position = 0.0f;
            }
            if (position > totalDistance)
            {
                position = totalDistance;
            }

            int i = 0;
            while (position > distances[i])
            {
                position -= distances[i];
                i++;
            }

            return points[i] + (points[i + 1] - points[i]) * (position / distances[i]);
        }


        public void AddPointReverse(Vector3 point)
        {
            InsertPoint(0, point);
        }

        public void AddPoint(Vector3 point)
        {
            InsertPoint(points.Count - 1, point);
        }

        private void InsertPoint(int index, Vector3 point)
        {
            points.Insert(index, point);

            // if this is not the last segment
            if (index != points.Count - 1)
            {
                // insert the new distance from index to index+1
                distances.Insert(index, (points[index + 1] - point).Length());
            }
            else
            {
                distances.Insert(index, 0.0f);
            }

            // update the distance of the previous segment
            if (index != 0)
            {
                distances[index-1] = (point - points[index]).Length();
            }
        }

        public void DebugPrint()
        {
            foreach (Vector3 p in points)
            {
                Console.WriteLine(p.X + ", " + p.Y + ", " + p.Z);
            }
        }

        //public void DebugDraw(Camera camera, GraphicsDevice device)
        //{
        //    BasicEffect effect = new BasicEffect(device);
        //    effect.EnableDefaultLighting();
        //    effect.World = Matrix.Identity;
        //    effect.Projection = camera.ProjectionMatrix;
        //    effect.View = camera.ViewMatrix;

        //    VertexPositionNormalTexture[] verts = new VertexPositionNormalTexture[points.Count];

        //    // copy path points to verts array
        //    for (int i = 0; i < points.Count; ++i)
        //    {
        //        verts[i].Position = points[i];
        //    }

        //    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
        //    {
        //        pass.Apply();
        //        device.DrawUserPrimitives(PrimitiveType.LineStrip, verts, 0, points.Count - 1);
        //    }
        //}


        public int GetPointCount()
        {
            return points.Count;
        }

        public Vector3 GetPoint(int index)
        {
            return points[index];
        }
    }
}
